//////////////////////////////////////////////////////
/////////////////////// UPDATED /////////////////////
//////////////////////////////////////////////////////
#include <WProgram.h>


#define MESSAGE_LENGTH 60
#define PROPERTY_LENGTH 6
#define PROPERTY_INDEX 0

#define TYPE_LENGTH 20
#define TYPE_INDEX 1

#define VALUE_CAP 6
#define VALUE_INDEX 2


// this class is in charge of parsing the serial message. It is based off Open Sound Control (OSC)
class OSC { 
private:
  char _message[MESSAGE_LENGTH];  
  char _type[TYPE_LENGTH];
  char _property[PROPERTY_LENGTH];
  int _value[VALUE_CAP];
  
  void sfcpy(char* dest, int destLength, char* src, int srcLength) {
    if(destLength >= srcLength) {
      strcpy(dest,src);
    }
    else {
      // debugging
      Serial.println("Destination too small. Source: ");
      Serial.println(src);
    }
  }      

public:
  OSC(char* mes, int mesLength) { 
    sfcpy(_message,MESSAGE_LENGTH,mes,mesLength);
    //Serial.println("constructor");
  }
  
  OSC(void) {}

  boolean setMessage(char *message, int messageLength) {
    char temp[MESSAGE_LENGTH];
    sfcpy(temp,MESSAGE_LENGTH,_message,MESSAGE_LENGTH);
    
    sfcpy(_message, MESSAGE_LENGTH, message, messageLength);
    
    if(parseMessage()) {
      //Serial.println("valid message");
      return true;
    } else {
      //Serial.println("invalid message");
      sfcpy(_message,MESSAGE_LENGTH,temp,MESSAGE_LENGTH);
      parseMessage();
      return false;
    }
  }    
   
  float getValueFloat(int index) {
    return _value[index];
  }
  
  int getValueInt(int index) {
    return (int)_value[index];
  } 
     
  
  boolean parseMessage() {
    //Serial.println("parsing");
    char*c;
    char mes[MESSAGE_LENGTH];
    strcpy(mes,_message);
    c = strtok(mes,"[]/!-");
    int index = PROPERTY_INDEX;
    
    int typeTagLength = 0;
    
    while(c != NULL) {
      if(index == PROPERTY_INDEX) sfcpy(_property,PROPERTY_LENGTH,c,sizeof(c));
      else if(index == TYPE_INDEX) {
         sfcpy(_type,TYPE_LENGTH,c,sizeof(c)); // c is just a pointer, sizeof return 2 (sizeof(char*))
         typeTagLength = (int)c;
      }
      else if(index == VALUE_INDEX) {
        _value[0] = atof(c);
        typeTagLength = (int)c - typeTagLength - 1;
      }
      else if(index == VALUE_INDEX+1) _value[1] = atoi(c);
      else if(index == VALUE_INDEX+2) _value[2] = atoi(c);
      else if(index == VALUE_INDEX+3) _value[3] = atoi(c);
      index++; // index ends higher than last valid token
      c = strtok(NULL,"[]/!-");    
    }
    
    /*
    Serial.print("type tag length: ");
    Serial.println(typeTagLength);
    
    Serial.print("index: ");
    Serial.println(index);
    
    Serial.print("value index: ");
    Serial.println(VALUE_INDEX);
    
    Serial.print("index-value_index: ");
    Serial.println(index-VALUE_INDEX);
    */
    
    if(index <= VALUE_INDEX) return false;
    if((index-VALUE_INDEX) != typeTagLength) return false;
    return true;
  }    
    
  void getProperty(char* prop) {

    strcpy(prop,_property);
  }
  
  void getType(char *type) {

    strcpy(type,_type);
  }

  void getValue(int* arr, int numElements) {
    //Serial.print("length: ");
    //Serial.println(arrLength);
    for(int i=0; i<min(numElements,VALUE_CAP); i++) {
      arr[i] = _value[i];
    }
  }    
};


